package com.sophialex.health.record.common.bind.swt.annotations;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.part.ViewPart;

// 不是为了多态，而是为了消除冗余
public abstract class AbstractBindingProcessor {
	protected ViewPart view;

	protected Field f;

	protected AnnotionProcessor parent;

	protected Class<?> lastElementType;

	protected AbstractBindingProcessor(ViewPart view, Field f, AnnotionProcessor parent) {
		this.view = view;

		this.f = f;
		// this.ba = ba;
		this.parent = parent;
	}

	public void process() {

		parent.out(". " + f.getName() + "[" + f.getType().getSimpleName() + "]");
		
		// 校验是否SWT部件
		validateSwtWiget(f);
		// 校验注解的属性是否为空

		vadidateAnnotation();
		String beanPath = getBeanPath();

		validatebeanPath(view.getClass(), beanPath);

		validateTypesMatch();

		bind();

	}

	protected abstract String getBeanPath();

	protected abstract void bind();
	

	// 校验UI与bean需要绑定的属性是否兼容，不好判断，先空着
	protected void validateTypesMatch() {
		// TODO Auto-generated method stub

	}

	protected void validatebeanPath(Class<?> parent, String curBeanPath) {
		String[] pathElements = curBeanPath.split("\\.");
		Field beanField = null;
		List<Field> fs = getFields(parent, true);
		for(Field f : fs) {
			if(f.getName().equals(pathElements[0]))
				beanField = f;
		}
		if(beanField == null) {
			Method get = getMethods(parent, "get" + Character.toUpperCase(pathElements[0].charAt(0)) + pathElements[0].substring(1), true);
			if(get == null)
				throw new BadBindingException("beanPath设置有误:" + parent.getSimpleName() + "不存在名为'" + pathElements[0] + "'的字段！");
			else{
				if(pathElements.length == 1) {
					lastElementType = get.getReturnType();
					return;
				} else {
					String newPath = curBeanPath.substring(curBeanPath.indexOf(".") + 1);
					validatebeanPath(get.getReturnType(), newPath);
				}
			}
				
		}else{
			beanField.setAccessible(true);
			if(pathElements.length == 1) {
				lastElementType = beanField.getType();
				return;
			} else {
				String newPath = curBeanPath.substring(curBeanPath.indexOf(".") + 1);
				validatebeanPath(beanField.getType(), newPath);
			}
		}
		
		
		// BeanInfo bi = null;
		// try {
		// bi = Introspector.getBeanInfo(parent.getClass());
		//
		// }
		// catch(IntrospectionException e2) {
		// e2.printStackTrace();
		// return;
		// }
		// PropertyDescriptor[] pds = bi.getPropertyDescriptors();
		// PropertyDescriptor cpds = null;
		// int i=0;
		// for( ;i < pds.length; i++) {
		// String propertyName = pds[i].getName();
		// if(propertyName.equals(pathElements[0])){
		// cpds = pds[i];
		// break;
		// }
		// }
		// if(i==pds.length){
		// throw new BadBindingException("beanPath设置有误:"
		// + parent.getSimpleName() + "不存在名为'" + pathElements[0]
		// + "'的字段！");
		//			                      		  
		// }
		// if (pathElements.length == 1) {
		// lastElementType = cpds.getPropertyType();
		// return;
		// } else {
		// String newPath = curBeanPath
		// .substring(curBeanPath.indexOf(".") + 1);
		// validatebeanPath(cpds.getPropertyType(), newPath);
		// }
	}

	protected List<Field> getFields(Class<?> clazz, boolean isTop) {
		List<Field> r = new ArrayList<Field>();
		Field[] fs = clazz.getDeclaredFields();
		for(Field f : fs) {
			if(isTop) {// 第一层
				f.setAccessible(true);
				r.add(f);
			} else {// 当前正在处理view的超类
				if(isValidFiledOfBaseClazz(f)) {
					f.setAccessible(true);
					r.add(f);
				}
			}
		}
		Class<?> sc = clazz.getSuperclass();
		if(ViewPart.class.isAssignableFrom(sc)) {
			r.addAll(getFields(sc, false));
		}
		return r;
	}

	protected Method getMethods(Class<?> clazz, String name, boolean isTop, Class<?>... parameterTypes) {
		Method m;

		try {
			m = clazz.getDeclaredMethod(name, parameterTypes);
			if(!isTop) {
				if(!isValidMethodOfBaseClazz(m)) {
					if(clazz.getSuperclass().equals(Object.class))
						m = null;
					else {
						m = getMethods(clazz.getSuperclass(), name, false, parameterTypes);
					}
				}
			}

		}
		catch(Exception e) {
			if(clazz.getSuperclass().equals(Object.class))
				m = null;
			else {
				m = getMethods(clazz.getSuperclass(), name, false, parameterTypes);
			}
		}
		return m;
		// if(!clazz.getSuperclass().equals(Object.class)){
		// m = getMethods(clazz.getSuperclass(), name, false,parameterTypes);
		// if(isValidMethodOfBaseClazz(m))
		// return m;
		// }else{
		// return null;
		// }
		// }else{
		//			
		// }
		// List<Method> r = new ArrayList<Method>();
		// Method[] fs = clazz.getDeclaredMethods();
		// for (Method f : fs) {
		// if (isTop) {//第一层
		// f.setAccessible(true);
		// r.add(f);
		// } else {//当前正在处理view的超类
		// if(isValidMethodOfBaseClazz(f)){
		// f.setAccessible(true);
		// r.add(f);
		// }
		// }
		// }
		// Class<?> sc = clazz.getSuperclass();
		// if(ViewPart.class.isAssignableFrom(sc)){
		// r.addAll(getMethods(sc,false));
		// }
		// return r;
	}

	private boolean isValidMethodOfBaseClazz(Method f2) {
		int m = f2.getModifiers();
		if(Modifier.isProtected(m) || Modifier.isPublic(m))
			return true;
		return false;
	}

	private boolean isValidFiledOfBaseClazz(Field f) {
		int m = f.getModifiers();
		if(Modifier.isProtected(m) || Modifier.isPublic(m))
			return true;
		return false;
	}

	protected abstract void vadidateAnnotation();

	protected void validateSwtWiget(Field f) {

		if(!f.getType().getName().startsWith("org.eclipse.swt.widgets.")) {
			throw new BadBindingException("字段" + view.getClass().getSimpleName() + "." + f.getName() + "[" + f.getType().getName() + "]不是有效的SWT部件");
		}

	}

	protected Control getControl(Field f) {
		Control ctl = null;
		try {
			ctl = (Control) f.get(view);
		}
		catch(Exception e) {
			e.printStackTrace();
			//System.exit(-1);
		}
		return ctl;
	}
	

	protected Object getFieldValue(Object o, String fieldName) {
		Object value = null;
		Field f = null;

		List<Field> fs = getFields(o.getClass(), true);
		for(Field f1 : fs) {
			if(f1.getName().equals(fieldName))
				f = f1;
		}
		if(f != null) {

			f.setAccessible(true);
			try {
				value = f.get(o);
			}
			catch(Exception e) {
				e.printStackTrace();
				//System.exit(-1);
			}
			return value;
		}
		// try {
		// f = o.getClass().getDeclaredField(fieldName);
		// f.setAccessible(true);
		// try {
		// value = f.get(o);
		// } catch (Exception e) {
		// e.printStackTrace();
		// System.exit(-1);
		// }
		//
		// } catch (Exception e) {
		// e.printStackTrace();
		// 若没有名为fieldName的字段，那尝试调用getter
		String name = "get" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
		// parent.out(name + "\r\n");
		Method getter = getMethods(o.getClass(), name, true);
		if(getter == null)
			throw new BadBindingException(o.getClass().getName() + "没有名为" + getter.getName() + "的方法");
		getter.setAccessible(true);
		// try {
		// getter = o.getClass().getDeclaredMethod(name);
		// getter.setAccessible(true);
		// } catch (Exception e1) {
		// e1.printStackTrace();
		// System.exit(-1);// 没办法了，退出
		// }
		try {
			value = getter.invoke(o);
		}
		catch(Exception e1) {
			e1.printStackTrace();
			//System.exit(-1);
		}
		return value;
		// }

		// return value;
	}

	
	
}
